<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
<meta name="viewport"
      content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">

    <meta name="author" content="WD">





<title>基于ResNet的MSTAR数据集目标分类 | WD&#39;s blog</title>



    <link rel="icon" href="/favicon1.ico">




    <!-- stylesheets list from _config.yml -->
    
    <link rel="stylesheet" href="/css/style.css">
    



    <!-- scripts list from _config.yml -->
    
    <script src="/js/script.js"></script>
    
    <script src="/js/tocbot.min.js"></script>
    
    <script src="/js/snow.js"></script>
    



    
    
        
            <!-- MathJax配置，可通过单美元符号书写行内公式等 -->
<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
    "HTML-CSS": {
        preferredFont: "TeX",
        availableFonts: ["STIX","TeX"],
        linebreaks: { automatic:true },
        EqnChunk: (MathJax.Hub.Browser.isMobile ? 10 : 50)
    },
    tex2jax: {
        inlineMath: [ ["$", "$"], ["\\(","\\)"] ],
        processEscapes: true,
        ignoreClass: "tex2jax_ignore|dno",
        skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
    },
    TeX: {
        equationNumbers: { autoNumber: "AMS" },
        noUndefined: { attributes: { mathcolor: "red", mathbackground: "#FFEEEE", mathsize: "90%" } },
        Macros: { href: "{}" }
    },
    messageStyle: "none"
    });
</script>
<!-- 给MathJax元素添加has-jax class -->
<script type="text/x-mathjax-config">
    MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for(i=0; i < all.length; i += 1) {
            all[i].SourceElement().parentNode.className += ' has-jax';
        }
    });
</script>
<!-- 通过连接CDN加载MathJax的js代码 -->
<script type="text/javascript" async
        src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML">
</script>


        
    


<meta name="generator" content="Hexo 5.4.0"></head>
<body>
    <div class="wrapper">
        <header>
    <nav class="navbar">
        <div class="container">
            <div class="navbar-header header-logo"><a href="/">WD&#39;s Blog</a></div>
            <div class="menu navbar-right">
                
                    <a class="menu-item" href="/archives">Posts</a>
                
                    <a class="menu-item" href="/category">Categories</a>
                
                    <a class="menu-item" href="/tag">Tags</a>
                
                    <a class="menu-item" href="/about">About</a>
                
                <input id="switch_default" type="checkbox" class="switch_default">
                <label for="switch_default" class="toggleBtn"></label>
            </div>
        </div>
    </nav>

    
    <nav class="navbar-mobile" id="nav-mobile">
        <div class="container">
            <div class="navbar-header">
                <div>
                    <a href="/">WD&#39;s Blog</a><a id="mobile-toggle-theme">·&nbsp;Light</a>
                </div>
                <div class="menu-toggle" onclick="mobileBtn()">&#9776; Menu</div>
            </div>
            <div class="menu" id="mobile-menu">
                
                    <a class="menu-item" href="/archives">Posts</a>
                
                    <a class="menu-item" href="/category">Categories</a>
                
                    <a class="menu-item" href="/tag">Tags</a>
                
                    <a class="menu-item" href="/about">About</a>
                
            </div>
        </div>
    </nav>

</header>
<script>
    var mobileBtn = function f() {
        var toggleMenu = document.getElementsByClassName("menu-toggle")[0];
        var mobileMenu = document.getElementById("mobile-menu");
        if(toggleMenu.classList.contains("active")){
           toggleMenu.classList.remove("active")
            mobileMenu.classList.remove("active")
        }else{
            toggleMenu.classList.add("active")
            mobileMenu.classList.add("active")
        }
    }
</script>
        <div class="main">
            <div class="container">
    
    
        <div class="post-toc">
    <div class="tocbot-list">
    </div>
    <div class="tocbot-list-menu">
        <a class="tocbot-toc-expand" onclick="expand_toc()">Expand all</a>
        <a onclick="go_top()">Back to top</a>
        <a onclick="go_bottom()">Go to bottom</a>
    </div>
</div>

<script>
    document.ready(
        function () {
            tocbot.init({
                tocSelector: '.tocbot-list',
                contentSelector: '.post-content',
                headingSelector: 'h1, h2, h3, h4, h5',
                collapseDepth: 1,
                orderedList: false,
                scrollSmooth: true,
            })
        }
    )

    function expand_toc() {
        var b = document.querySelector(".tocbot-toc-expand");
        tocbot.init({
            tocSelector: '.tocbot-list',
            contentSelector: '.post-content',
            headingSelector: 'h1, h2, h3, h4, h5',
            collapseDepth: 6,
            orderedList: false,
            scrollSmooth: true,
        });
        b.setAttribute("onclick", "collapse_toc()");
        b.innerHTML = "Collapse all"
    }

    function collapse_toc() {
        var b = document.querySelector(".tocbot-toc-expand");
        tocbot.init({
            tocSelector: '.tocbot-list',
            contentSelector: '.post-content',
            headingSelector: 'h1, h2, h3, h4, h5',
            collapseDepth: 1,
            orderedList: false,
            scrollSmooth: true,
        });
        b.setAttribute("onclick", "expand_toc()");
        b.innerHTML = "Expand all"
    }

    function go_top() {
        window.scrollTo(0, 0);
    }

    function go_bottom() {
        window.scrollTo(0, document.body.scrollHeight);
    }

</script>
    

    
    <article class="post-wrap">
        <header class="post-header">
            <h1 class="post-title">基于ResNet的MSTAR数据集目标分类</h1>
            
                <div class="post-meta">
                    
                        Author: <a itemprop="author" rel="author" href="/about/">WD</a>
                     &nbsp;

                    
                        <span class="post-time">
                        Date: <a href="#">July 5, 2021&nbsp;&nbsp;17:51:09</a>
                        </span>
                     &nbsp;
                    
                        <span class="post-category">
                    Category:
                            
                                <a href="/categories/%E7%9B%AE%E6%A0%87%E6%A3%80%E6%B5%8B/">目标检测</a>
                            
                        </span>
    <script async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
    <br>
    <span id="busuanzi_container_site_pv">总阅读量:<a href="#"><span id="busuanzi_value_page_pv"></span></a>次</span>&nbsp;
    <span class="post-count">文章字数:<a href="#">3.2k</span></a>&nbsp;
     <span class="post-count">阅读时长:<a href="#">15</span>min</a>
                    
                </div>
            
        </header>

        <div class="post-content">
            <h2 id="说在前面"><a href="#说在前面" class="headerlink" title="说在前面"></a>说在前面</h2><ul>
<li>前两篇文章主要讨论了CNN的原理 <a target="_blank" rel="noopener" href="https://blog.csdn.net/qq_40181592/article/details/115252377">https://blog.csdn.net/qq_40181592/article/details/115252377</a> 和CNN网络模型的发展史 <a target="_blank" rel="noopener" href="https://blog.csdn.net/qq_40181592/article/details/115487195">https://blog.csdn.net/qq_40181592/article/details/115487195</a> ，毕业设计主要采用的模型是ResNet，采用的SAR图像数据集是MSTAR数据集，代码采用Tensorflow2.2 GPU 结构，这篇文章将介绍具体实现过程。</li>
</ul>
<h2 id="1-MSART数据集介绍"><a href="#1-MSART数据集介绍" class="headerlink" title="1. MSART数据集介绍"></a>1. MSART数据集介绍</h2><ul>
<li><p>本次实验采用美国公开的运动和静止目标获取与识别（Moving and Stationary Target Acquisition and Recognition, MSTAR）数据集。<strong>数据集可在百度下载，实在找不到的可以私聊我</strong>，选用标准工作条件（Standard Operating Conditions, SOC）下十类车辆目标的SAR图像作为实验数据，这些车辆目标是：2S1、BMP2、BRDM2、BTR60、BTR70、D7、T62、T72、ZIL131、ZSU23/4。每个类别的光学图像和SAR图像如下图所示：</p>
<p><img src="https://img-blog.csdnimg.cn/20210705174326130.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMTgxNTky,size_16,color_FFFFFF,t_70#pic_center" style="zoom:120%;" /></p>
</li>
<li><p>各类SAR数据均包含0°~360°方位角的目标，本次实验选用17°俯仰角下拍摄的SAR图像作为训练集，15°俯仰角下拍摄的SAR图像作为测试集，这样选择可以验证特征提取方法的泛化能力。训练和测试数据的目标类型和数量在表中列出。</p>
<p>|  类别   | 训练集数量（17°） | 测试集数量（15°） |<br>| :——-: | :———————-: | :———————-: |<br>|   2S1   |        299        |        274        |<br>|  BMP2   |        233        |        196        |<br>|  BRDM2  |        298        |        274        |<br>|  BTR60  |        256        |        195        |<br>|  BTR70  |        233        |        196        |<br>|   D7    |        299        |        274        |<br>|   T62   |        299        |        273        |<br>|   T72   |        232        |        196        |<br>| ZIL131  |        299        |        274        |<br>| ZSU23/4 |        299        |        274        |<br>|  总计   |       2747        |       2426        |</p>
</li>
</ul>
<h2 id="2-SAR目标分类网络"><a href="#2-SAR目标分类网络" class="headerlink" title="2. SAR目标分类网络"></a>2. SAR目标分类网络</h2><ul>
<li><p>残差网络（Residual Network, ResNet）解决了深度卷积神经网络的退化问题，可以训练更深的网络，并且收敛更快，另一方面，神经网络在反向传播时，容易出现梯度消失或梯度爆炸，梯度消失会导致底层的参数不能得到有效更新，梯度爆炸会使梯度以指数级速度增大，造成系统不稳定，在深层网络中这种现象更明显，而ResNet通过引入跳跃连接（Shortcut Connections）很好地解决了这些问题。对于SAR目标特征提取来说，需要更深层次地提取原始SAR目标特征，就避免不了上述问题，所以本节采用ResNet作为基础网络结构。</p>
</li>
<li><p>ResNet的基本残差单元如下图所示，在正常的卷积层旁边增加了一个恒等映射（Identity Mapping），相当于走了一个捷径，这就可以将当前的输出X直接传给下一层网络，最终所学的H(X) = F(X) + X，同时在反向传播过程中，也可以通过这条捷径直接把梯度传递给上一层，这就一定程度解决了梯度消失问题。</p>
<p><img src="https://img-blog.csdnimg.cn/20210705174421716.png#pic_center" alt="image-20210705171010872"></p>
</li>
<li><p>本节设计的SAR地面军事目标深度卷积神经网络结构如下图所示：</p>
<p><img src="https://img-blog.csdnimg.cn/2021070517443892.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMTgxNTky,size_16,color_FFFFFF,t_70#pic_center" style="zoom: 100%;" /></p>
</li>
<li><p>图中每一个残差单元是由三个卷积层和一个跳跃连接组成，每个卷积包括卷积层、BN层和ReLU激活函数层，跳跃连接处是一个1×1的卷积层，它改变的是输入特征的通道数，方便和正常卷积结果相加传送到下一层。其中BN层会对每层的输出结果进行归一化操作，最重要的作用是加速网络的收敛速度，抑制过拟合，提高网络的泛化能力。</p>
</li>
<li>SAR图像在输入前一般要进行预处理，要进行统一尺寸、图像增强等，方便后面卷积神经网络提取特征，预处理方法将在实验部分阐述。将预处理后的SAR图像输入到上述网络中，按照的卷积、池化、融合等进行正向传播，最终经过全连接层的输出通过Softmax分类器，得到一个向量，其中表示每个SAR图像类别的概率，然后计算分类交叉熵损失，再进行反向传播计算梯度，更新卷积核的参数，使损失函数最小，这样循环上述过程，迭代一定次数，损失趋于稳定，就训练好该SAR目标分类网络了。</li>
</ul>
<h2 id="3-ResNet代码及训练"><a href="#3-ResNet代码及训练" class="headerlink" title="3. ResNet代码及训练"></a>3. ResNet代码及训练</h2><ul>
<li><p>ResNet的基本残差单元代码如下：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">BasicBlock_3</span>(<span class="params">layers.Layer</span>):</span></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">__init__</span>(<span class="params">self, filter_num, stride=<span class="number">1</span></span>):</span></span><br><span class="line">        <span class="built_in">super</span>(BasicBlock_3, self).__init__()</span><br><span class="line"></span><br><span class="line">        self.conv1 = layers.Conv2D(filter_num, (<span class="number">1</span>, <span class="number">1</span>), strides=stride, padding=<span class="string">&#x27;same&#x27;</span>)</span><br><span class="line">        self.bn1 = layers.BatchNormalization()</span><br><span class="line">        self.relu1 = layers.Activation(<span class="string">&#x27;relu&#x27;</span>)</span><br><span class="line"></span><br><span class="line">        self.conv2 = layers.Conv2D(filter_num, (<span class="number">3</span>, <span class="number">3</span>), strides=<span class="number">1</span>, padding=<span class="string">&#x27;same&#x27;</span>)</span><br><span class="line">        self.bn2 = layers.BatchNormalization()</span><br><span class="line">        self.relu2 = layers.Activation(<span class="string">&#x27;relu&#x27;</span>)</span><br><span class="line"></span><br><span class="line">        self.conv3 = layers.Conv2D(<span class="number">4</span> * filter_num, (<span class="number">1</span>, <span class="number">1</span>), strides=<span class="number">1</span>, padding=<span class="string">&#x27;same&#x27;</span>)</span><br><span class="line">        self.bn3 = layers.BatchNormalization()</span><br><span class="line"></span><br><span class="line">        self.downsample = Sequential()</span><br><span class="line">        self.downsample.add(layers.Conv2D(<span class="number">4</span> * filter_num, (<span class="number">1</span>, <span class="number">1</span>), strides=stride))</span><br><span class="line">        self.downsample.add(layers.BatchNormalization())</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">call</span>(<span class="params">self, inputs, training=<span class="literal">None</span></span>):</span></span><br><span class="line">        </span><br><span class="line">        <span class="comment"># [b, h, w, c]</span></span><br><span class="line">        out = self.conv1(inputs)</span><br><span class="line">        out = self.bn1(out)</span><br><span class="line">        out = self.relu1(out)</span><br><span class="line"></span><br><span class="line">        out = self.conv2(out)</span><br><span class="line">        out = self.bn2(out)</span><br><span class="line">        out = self.relu1(out)</span><br><span class="line"></span><br><span class="line">        out = self.conv3(out)</span><br><span class="line">        out = self.bn3(out)</span><br><span class="line">        </span><br><span class="line">        identity = self.downsample(inputs)</span><br><span class="line"></span><br><span class="line">        output = layers.add([out, identity])</span><br><span class="line">        output = tf.nn.relu(output)</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> output</span><br></pre></td></tr></table></figure>
</li>
<li><p>设计ResNet50的代码如下</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">ResNet_50</span>(<span class="params">keras.Model</span>):</span></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">__init__</span>(<span class="params">self, layer_dims, num_class=<span class="number">10</span></span>):</span> <span class="comment"># [3, 4, 6, 3]</span></span><br><span class="line">        <span class="built_in">super</span>(ResNet_50, self).__init__()</span><br><span class="line"></span><br><span class="line">        self.stem = Sequential([layers.Conv2D(<span class="number">64</span>, (<span class="number">5</span>,<span class="number">5</span>), strides=(<span class="number">2</span>, <span class="number">2</span>), padding=<span class="string">&#x27;same&#x27;</span>),</span><br><span class="line">                                layers.BatchNormalization(),</span><br><span class="line">                                layers.Activation(<span class="string">&#x27;relu&#x27;</span>),</span><br><span class="line">                                layers.MaxPool2D(pool_size=(<span class="number">2</span>, <span class="number">2</span>), strides=(<span class="number">2</span>, <span class="number">2</span>), padding=<span class="string">&#x27;same&#x27;</span>)</span><br><span class="line">                               ])   </span><br><span class="line"></span><br><span class="line">        self.layer1 = self.build_resblock(<span class="number">64</span>, layer_dims[<span class="number">0</span>])</span><br><span class="line">        self.layer2 = self.build_resblock(<span class="number">128</span>, layer_dims[<span class="number">1</span>], stride=<span class="number">2</span>)</span><br><span class="line">        self.layer3 = self.build_resblock(<span class="number">256</span>, layer_dims[<span class="number">2</span>], stride=<span class="number">2</span>)</span><br><span class="line">        self.layer4 = self.build_resblock(<span class="number">512</span>, layer_dims[<span class="number">3</span>], stride=<span class="number">2</span>)</span><br><span class="line"></span><br><span class="line">        self.avgpool = layers.GlobalAveragePooling2D()</span><br><span class="line">        self.fc = layers.Dense(num_class)</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">call</span>(<span class="params">self, inputs, training=<span class="literal">None</span></span>):</span></span><br><span class="line">        </span><br><span class="line">        x = self.stem(inputs)</span><br><span class="line">        x = self.layer1(x)</span><br><span class="line">        x = self.layer2(x)</span><br><span class="line">        x = self.layer3(x)</span><br><span class="line">        x = self.layer4(x)</span><br><span class="line">        <span class="comment"># [b, c]</span></span><br><span class="line">        x = self.avgpool(x)</span><br><span class="line">        <span class="comment"># [b. 100]</span></span><br><span class="line">        x = self.fc(x)</span><br><span class="line">        <span class="keyword">return</span> x</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">build_resblock</span>(<span class="params">self, filter_num, blocks, stride=<span class="number">1</span></span>):</span></span><br><span class="line"></span><br><span class="line">        res_block = Sequential()</span><br><span class="line"></span><br><span class="line">        res_block.add(BasicBlock_3(filter_num, stride))</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> _ <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, blocks):</span><br><span class="line">            res_block.add(BasicBlock_3(filter_num, stride=<span class="number">1</span>))</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">return</span> res_block</span><br></pre></td></tr></table></figure>
</li>
<li><p>首先将所有类别的SAR原始图像裁剪为统一尺寸128×128，利用幂函数增强（Gamma变换）来提高暗部细节，Gamma变换公式如下：</p>
<script type="math/tex; mode=display">
V_{out} = AV_{in}^\gamma</script><p>其中$\gamma$ 取0.6，下图左边是前五个类别的原始SAR图像，右边是经过预处理之后的SAR图像，可以观察到SAR图像整体的对比度提高了，暗部细节也增强了。</p>
<p><img src="https://img-blog.csdnimg.cn/20210705174510583.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMTgxNTky,size_16,color_FFFFFF,t_70#pic_center" alt=""></p>
</li>
<li><p>CNN网络模型代码采用Tensorflow2.2 GPU框架，实验采用了自适应学习率优化算法（Adam），学习率设置为0.001，Batch-Size设置为16，训练次数epoch设置为50。训练过程采用TensorBoard工具来监控并存储log文件。具体训练代码如下：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">model = resnet50()</span><br><span class="line">model.build(input_shape=(<span class="literal">None</span>, <span class="number">128</span>, <span class="number">128</span>, <span class="number">1</span>))</span><br><span class="line">model.summary()</span><br><span class="line">current_time = datetime.datetime.now().strftime(<span class="string">&quot;%Y%m%d-%H%M%S&quot;</span>)</span><br><span class="line">log_dir = <span class="string">&#x27;logs/ResNet50_epoch50_Mstar_&#x27;</span> + current_time</span><br><span class="line">tb_callback = callbacks.TensorBoard(log_dir=log_dir)</span><br><span class="line"></span><br><span class="line">model.<span class="built_in">compile</span>(optimizer=optimizers.Adam(lr=<span class="number">0.0001</span>), loss=tf.losses.CategoricalCrossentropy(from_logits=<span class="literal">True</span>),</span><br><span class="line">            metrics=[<span class="string">&#x27;accuracy&#x27;</span>])</span><br><span class="line">    <span class="comment">#model.fit(train_db, epochs=1, validation_data=test_db,validation_freq=1)</span></span><br><span class="line">model.fit(train_db, epochs=<span class="number">50</span>, validation_data=test_db,validation_freq=<span class="number">1</span>,callbacks=[tb_callback])</span><br><span class="line">    </span><br><span class="line">model.evaluate(test_db)</span><br></pre></td></tr></table></figure>
</li>
<li><p>训练的Loss曲线和Accuracy曲线如下：</p>
<p><img src="https://img-blog.csdnimg.cn/20210705174536874.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMTgxNTky,size_16,color_FFFFFF,t_70#pic_center" style="zoom:80%;" /></p>
<p><img src="https://img-blog.csdnimg.cn/20210705174545158.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMTgxNTky,size_16,color_FFFFFF,t_70#pic_center" style="zoom:80%;" /></p>
<p>图中红色标签代表训练集，蓝色标签代表验证集，从曲线可以看出随着epoch的增大，Loss值逐渐下降，Accuracy值逐渐升高，没有出现过拟合现象，网络训练较好，符合预期。</p>
</li>
<li><p>用MSTAR数据的测试集在训练好的CNN模型中进行预测，使用5.2节的分类参数评估CNN模型，通过预测结果绘制十类SAR目标的混淆矩阵如下图所示：</p>
<p><img src="https://img-blog.csdnimg.cn/20210705174609338.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMTgxNTky,size_16,color_FFFFFF,t_70#pic_center" style="zoom:80%;" /></p>
</li>
<li><p>横坐标为预测类别，纵坐标为真实类别，对角线的值就是预测正确的准确率，使用Python的Seaborn库绘制混淆矩阵图。可以看到设计的CNN模型对于每个类别都有较高的识别率。</p>
</li>
</ul>
<h2 id="4-结尾"><a href="#4-结尾" class="headerlink" title="4. 结尾"></a>4. 结尾</h2><ul>
<li>本次毕设实验采用的ResNet网络对MSATR数据集进行训练和预测，给出了混淆矩阵和识别率，后面会采用LBP+SVM 和CLBP+SVM 两种传统的特征提取算法同样对MSTAR数据集进行提取，对比分析三种方法的效果。</li>
</ul>
<h2 id="附录（代码）"><a href="#附录（代码）" class="headerlink" title="附录（代码）"></a>附录（代码）</h2><ul>
<li>由于搭建ResNet的代码前面已经给出，在此不再重复，下面给出具体读取数据集和预处理及训练的代码。</li>
</ul>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> tensorflow <span class="keyword">as</span> tf </span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">from</span> ResNet <span class="keyword">import</span> resnet50</span><br><span class="line"><span class="keyword">from</span> tensorflow <span class="keyword">import</span> keras</span><br><span class="line"><span class="keyword">from</span> tensorflow.keras <span class="keyword">import</span> datasets, layers, optimizers, Sequential, callbacks</span><br><span class="line"><span class="keyword">from</span> sklearn.metrics <span class="keyword">import</span> accuracy_score, confusion_matrix, recall_score, precision_score, f1_score, fbeta_score</span><br><span class="line"><span class="keyword">from</span> sklearn.metrics <span class="keyword">import</span> roc_auc_score, roc_curve, auc, classification_report</span><br><span class="line"><span class="keyword">from</span> sklearn.preprocessing <span class="keyword">import</span> label_binarize</span><br><span class="line"><span class="keyword">from</span> sklearn.model_selection <span class="keyword">import</span> train_test_split</span><br><span class="line"><span class="keyword">from</span> matplotlib <span class="keyword">import</span> pyplot <span class="keyword">as</span> plt</span><br><span class="line"><span class="keyword">import</span> pathlib</span><br><span class="line"><span class="keyword">import</span> datetime</span><br><span class="line"><span class="keyword">import</span> seaborn <span class="keyword">as</span> sns</span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">load_one_from_path_label</span>(<span class="params">path, label</span>):</span></span><br><span class="line">    images = np.zeros((<span class="number">1</span>, <span class="number">128</span>, <span class="number">128</span>, <span class="number">1</span>))</span><br><span class="line">    labels = tf.one_hot(label, depth=<span class="number">10</span>)</span><br><span class="line">    labels = tf.cast(labels, dtype=tf.int32)</span><br><span class="line"></span><br><span class="line">    image = tf.io.read_file(path)</span><br><span class="line">    image = tf.image.decode_jpeg(image)</span><br><span class="line">    image = tf.image.adjust_gamma(image, <span class="number">0.6</span>)  <span class="comment"># Gamma </span></span><br><span class="line">    image = tf.image.resize(image, [<span class="number">128</span>, <span class="number">128</span>])  <span class="comment"># 重设为(128, 128)</span></span><br><span class="line">    image = tf.cast(image, dtype=tf.float32) / <span class="number">255.0</span>  <span class="comment"># 归一化到[0,1]范围</span></span><br><span class="line">        </span><br><span class="line">    images[<span class="number">0</span>, :, :, :] = image</span><br><span class="line">    <span class="keyword">return</span> images, labels</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">load_from_path_label2</span>(<span class="params">all_image_paths, all_image_labels</span>):</span></span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;读取所有图片&#x27;&#x27;&#x27;</span></span><br><span class="line">    image_count = <span class="built_in">len</span>(all_image_paths)</span><br><span class="line">    images = np.zeros((image_count, <span class="number">128</span>, <span class="number">128</span>, <span class="number">1</span>))</span><br><span class="line">    labels = tf.one_hot(all_image_labels, depth=<span class="number">10</span>)</span><br><span class="line">    labels = tf.cast(all_image_labels, dtype=tf.int32)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, image_count):</span><br><span class="line">        image = tf.io.read_file(all_image_paths[i])</span><br><span class="line">        image = tf.image.decode_jpeg(image)</span><br><span class="line">        image = tf.image.adjust_gamma(image, <span class="number">0.6</span>)  <span class="comment"># Gamma </span></span><br><span class="line">        image = tf.image.resize(image, [<span class="number">128</span>, <span class="number">128</span>])  <span class="comment"># 重设为(128, 128)</span></span><br><span class="line">        image = tf.cast(image, dtype=tf.float32) / <span class="number">255.0</span>  <span class="comment"># 归一化到[0,1]范围</span></span><br><span class="line">        </span><br><span class="line">        images[i, :, :, :] = image</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> images, labels</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">load_from_path_label</span>(<span class="params">path, label</span>):</span></span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;读取图片&#x27;&#x27;&#x27;</span></span><br><span class="line">    image = tf.io.read_file(path)</span><br><span class="line">    image = tf.image.decode_jpeg(image)</span><br><span class="line">    label = tf.one_hot(label, depth=<span class="number">10</span>)</span><br><span class="line">    label = tf.cast(label, dtype=tf.int32)</span><br><span class="line">    <span class="keyword">return</span> image, label</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">preprocess</span>(<span class="params">image, label</span>):</span></span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;图片预处理&#x27;&#x27;&#x27;</span></span><br><span class="line">    </span><br><span class="line">    image = tf.image.adjust_gamma(image, <span class="number">0.6</span>)  <span class="comment"># Gamma </span></span><br><span class="line">    image = tf.image.resize(image, [<span class="number">128</span>, <span class="number">128</span>])  <span class="comment"># 重设为(128, 128)</span></span><br><span class="line">    image = tf.cast(image, dtype=tf.float32) / <span class="number">255.0</span>  <span class="comment"># 归一化到[0,1]范围</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> image, label</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">show_image</span>(<span class="params">db, row, col, title, is_preprocess=<span class="literal">True</span></span>):</span></span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;显示10个类别图片&#x27;&#x27;&#x27;</span></span><br><span class="line">    plt.figure()</span><br><span class="line">    plt.suptitle(title, fontsize=<span class="number">14</span>)</span><br><span class="line">    j = <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> i, (image, label) <span class="keyword">in</span> <span class="built_in">enumerate</span>(db):</span><br><span class="line">        <span class="keyword">if</span> j == row * col :</span><br><span class="line">            <span class="keyword">break</span></span><br><span class="line">        <span class="keyword">if</span> <span class="built_in">int</span>(tf.argmax(label)) == <span class="built_in">int</span>(j / col) :</span><br><span class="line">            <span class="keyword">if</span> is_preprocess == <span class="literal">True</span> :</span><br><span class="line">                image = image * <span class="number">255</span></span><br><span class="line">            plt.subplot(row, col, j+<span class="number">1</span>)</span><br><span class="line">            plt.title(<span class="string">&quot;class&quot;</span> + <span class="built_in">str</span>(<span class="built_in">int</span>(tf.argmax(label))), fontsize=<span class="number">8</span>)</span><br><span class="line">            plt.imshow(image, cmap=<span class="string">&#x27;gray&#x27;</span>)</span><br><span class="line">            plt.axis(<span class="string">&#x27;off&#x27;</span>)</span><br><span class="line">            j = j + <span class="number">1</span></span><br><span class="line">    plt.tight_layout()</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_datasets</span>(<span class="params">path, train=<span class="literal">True</span></span>):</span></span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;获取数据集&#x27;&#x27;&#x27;</span></span><br><span class="line">    <span class="comment"># 获得数据集文件路径</span></span><br><span class="line">    data_path = pathlib.Path(path)</span><br><span class="line">    <span class="comment"># 获得所有类别图片的路径</span></span><br><span class="line">    all_image_paths = <span class="built_in">list</span>(data_path.glob(<span class="string">&#x27;*/*&#x27;</span>))</span><br><span class="line">    all_image_paths = [<span class="built_in">str</span>(path1) <span class="keyword">for</span> path1 <span class="keyword">in</span> all_image_paths]</span><br><span class="line">    <span class="comment"># 数据集图片数量</span></span><br><span class="line">    image_count = <span class="built_in">len</span>(all_image_paths)</span><br><span class="line">    <span class="comment"># 获得类别名称列表</span></span><br><span class="line">    label_names = [item.name <span class="keyword">for</span> item <span class="keyword">in</span> data_path.glob(<span class="string">&#x27;*/&#x27;</span>)]</span><br><span class="line">    <span class="comment"># 枚举类别名称并转化为数字标号</span></span><br><span class="line">    label_index = <span class="built_in">dict</span>((name, index) <span class="keyword">for</span> index, name <span class="keyword">in</span> <span class="built_in">enumerate</span>(label_names))</span><br><span class="line">    <span class="built_in">print</span>(label_index)</span><br><span class="line">    <span class="built_in">print</span>(label_names)</span><br><span class="line">    <span class="built_in">print</span>(image_count)</span><br><span class="line">    <span class="comment"># 获得所有数据集图片的数字标号</span></span><br><span class="line">    all_image_labels = [label_index[pathlib.Path(path).parent.name] <span class="keyword">for</span> path <span class="keyword">in</span> all_image_paths]</span><br><span class="line">    <span class="keyword">for</span> image, label <span class="keyword">in</span> <span class="built_in">zip</span>(all_image_paths[:<span class="number">5</span>], all_image_labels[:<span class="number">5</span>]):</span><br><span class="line">        <span class="built_in">print</span>(image, <span class="string">&#x27; ---&gt;  &#x27;</span>, label)</span><br><span class="line">    images, labels = load_from_path_label2(all_image_paths, all_image_labels)</span><br><span class="line">    <span class="comment"># 建立dataset数据集</span></span><br><span class="line">    db = tf.data.Dataset.from_tensor_slices((all_image_paths, all_image_labels)) </span><br><span class="line">    db = db.<span class="built_in">map</span>(load_from_path_label)</span><br><span class="line">    <span class="keyword">if</span> train == <span class="literal">True</span>:</span><br><span class="line">        show_image(db, <span class="number">5</span>, <span class="number">5</span>, <span class="string">&#x27;(Train) Raw SAR Image&#x27;</span>, <span class="literal">False</span>)</span><br><span class="line">        db = db.<span class="built_in">map</span>(preprocess)</span><br><span class="line">        show_image(db, <span class="number">5</span>, <span class="number">5</span>, <span class="string">&#x27;(Train) Preprocessed SAR Image&#x27;</span>, <span class="literal">True</span>)</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        show_image(db, <span class="number">5</span>, <span class="number">5</span>, <span class="string">&#x27;(Test) Raw SAR Image&#x27;</span>, <span class="literal">False</span>)</span><br><span class="line">        db = db.<span class="built_in">map</span>(preprocess)</span><br><span class="line">        show_image(db, <span class="number">5</span>, <span class="number">5</span>, <span class="string">&#x27;(Test) Preprocessed SAR Image&#x27;</span>, <span class="literal">True</span>)</span><br><span class="line">    </span><br><span class="line">    db = db.shuffle(<span class="number">1000</span>).batch(<span class="number">16</span>)</span><br><span class="line">    <span class="keyword">return</span> db, images, labels, label_names</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_train_valid_datasets</span>(<span class="params">path, train=<span class="literal">True</span></span>):</span></span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;获取数据集&#x27;&#x27;&#x27;</span></span><br><span class="line">    <span class="comment"># 获得数据集文件路径</span></span><br><span class="line">    data_path = pathlib.Path(path)</span><br><span class="line">    <span class="comment"># 获得所有类别图片的路径</span></span><br><span class="line">    all_image_paths = <span class="built_in">list</span>(data_path.glob(<span class="string">&#x27;*/*&#x27;</span>))</span><br><span class="line">    all_image_paths = [<span class="built_in">str</span>(path1) <span class="keyword">for</span> path1 <span class="keyword">in</span> all_image_paths]</span><br><span class="line">    <span class="comment"># 数据集图片数量</span></span><br><span class="line">    image_count = <span class="built_in">len</span>(all_image_paths)</span><br><span class="line">    <span class="comment"># 获得类别名称列表</span></span><br><span class="line">    label_names = [item.name <span class="keyword">for</span> item <span class="keyword">in</span> data_path.glob(<span class="string">&#x27;*/&#x27;</span>)]</span><br><span class="line">    <span class="comment"># 枚举类别名称并转化为数字标号</span></span><br><span class="line">    label_index = <span class="built_in">dict</span>((name, index) <span class="keyword">for</span> index, name <span class="keyword">in</span> <span class="built_in">enumerate</span>(label_names))</span><br><span class="line">    <span class="built_in">print</span>(label_index)</span><br><span class="line">    <span class="built_in">print</span>(label_names)</span><br><span class="line">    <span class="built_in">print</span>(image_count)</span><br><span class="line">    <span class="comment"># 获得所有数据集图片的数字标号</span></span><br><span class="line">    all_image_labels = [label_index[pathlib.Path(path).parent.name] <span class="keyword">for</span> path <span class="keyword">in</span> all_image_paths]</span><br><span class="line">    <span class="keyword">for</span> image, label <span class="keyword">in</span> <span class="built_in">zip</span>(all_image_paths[:<span class="number">5</span>], all_image_labels[:<span class="number">5</span>]):</span><br><span class="line">        <span class="built_in">print</span>(image, <span class="string">&#x27; ---&gt;  &#x27;</span>, label)</span><br><span class="line">    </span><br><span class="line">    train_images, valid_images, train_labels, valid_labels = train_test_split(all_image_paths, all_image_labels, test_size = <span class="number">0.2</span>, random_state = <span class="number">0</span>)</span><br><span class="line"></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;train counts -----&gt; &#x27;</span>,<span class="built_in">len</span>(train_images))</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;valid counts -----&gt; &#x27;</span>,<span class="built_in">len</span>(valid_images))</span><br><span class="line">    train_db = tf.data.Dataset.from_tensor_slices((train_images, train_labels)) </span><br><span class="line">    train_db = train_db.<span class="built_in">map</span>(load_from_path_label)</span><br><span class="line"></span><br><span class="line">    valid_db = tf.data.Dataset.from_tensor_slices((valid_images, valid_labels)) </span><br><span class="line">    valid_db = valid_db.<span class="built_in">map</span>(load_from_path_label)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> train == <span class="literal">True</span>:</span><br><span class="line">        show_image(train_db, <span class="number">5</span>, <span class="number">5</span>, <span class="string">&#x27;(Train) Raw SAR Image&#x27;</span>, <span class="literal">False</span>)</span><br><span class="line">        train_db = train_db.<span class="built_in">map</span>(preprocess)</span><br><span class="line">        show_image(train_db, <span class="number">5</span>, <span class="number">5</span>, <span class="string">&#x27;(Train) Preprocessed SAR Image&#x27;</span>, <span class="literal">True</span>)</span><br><span class="line"></span><br><span class="line">        show_image(valid_db, <span class="number">5</span>, <span class="number">5</span>, <span class="string">&#x27;(Valid) Raw SAR Image&#x27;</span>, <span class="literal">False</span>)</span><br><span class="line">        valid_db = valid_db.<span class="built_in">map</span>(preprocess)</span><br><span class="line">        show_image(valid_db, <span class="number">5</span>, <span class="number">5</span>, <span class="string">&#x27;(Valid) Preprocessed SAR Image&#x27;</span>, <span class="literal">True</span>)</span><br><span class="line">    </span><br><span class="line">    train_db = train_db.shuffle(<span class="number">1000</span>).batch(<span class="number">16</span>)</span><br><span class="line">    valid_db = valid_db.shuffle(<span class="number">1000</span>).batch(<span class="number">16</span>)</span><br><span class="line">    <span class="keyword">return</span> train_db, valid_db</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">plot_confusion_matrix</span>(<span class="params">matrix, class_labels, normalize=<span class="literal">False</span></span>):</span></span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;混淆矩阵绘图&#x27;&#x27;&#x27;</span></span><br><span class="line">    <span class="keyword">if</span> normalize:</span><br><span class="line">        matrix = matrix.astype(<span class="string">&#x27;float&#x27;</span>) / matrix.<span class="built_in">sum</span>(axis=<span class="number">1</span>)[:, np.newaxis] <span class="comment"># 混淆矩阵归一化  </span></span><br><span class="line">        A = np.around(matrix, decimals=<span class="number">5</span>)</span><br><span class="line">        A = A * <span class="number">100</span></span><br><span class="line">        <span class="built_in">print</span>(A)</span><br><span class="line">        matrix = np.around(matrix, decimals=<span class="number">2</span>)</span><br><span class="line">    sns.<span class="built_in">set</span>()</span><br><span class="line">    f, ax = plt.subplots()</span><br><span class="line">    tick_marks = np.arange(<span class="number">0.5</span>,<span class="number">10.5</span>,<span class="number">1</span>)</span><br><span class="line">    sns.heatmap(matrix, annot=<span class="literal">True</span>, cmap=<span class="string">&quot;Blues&quot;</span>,ax=ax) <span class="comment">#画热力图</span></span><br><span class="line">    ax.set_title(<span class="string">&#x27;confusion matrix&#x27;</span>) <span class="comment">#标题</span></span><br><span class="line">    </span><br><span class="line">    plt.xticks(tick_marks, class_labels, rotation=<span class="number">45</span>)</span><br><span class="line">    plt.yticks(tick_marks, class_labels, rotation=<span class="number">0</span>)</span><br><span class="line">    ax.set_xlabel(<span class="string">&#x27;Predict&#x27;</span>) <span class="comment">#x轴</span></span><br><span class="line">    ax.set_ylabel(<span class="string">&#x27;True&#x27;</span>) <span class="comment">#y轴</span></span><br><span class="line">    plt.tight_layout()</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">main</span>():</span>    </span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;main函数&#x27;&#x27;&#x27;</span></span><br><span class="line">    train_db, train_images, train_labels, train_label_names = get_datasets(<span class="string">&#x27;E:\\SARimage\\TRAIN&#x27;</span>, <span class="literal">True</span>)</span><br><span class="line">    test_db, test_images, test_labels, test_label_names = get_datasets(<span class="string">&#x27;E:\\SARimage\\TEST&#x27;</span>, <span class="literal">False</span>)</span><br><span class="line">    <span class="comment"># resnet 50</span></span><br><span class="line">    model = resnet50()</span><br><span class="line">    model.build(input_shape=(<span class="literal">None</span>, <span class="number">128</span>, <span class="number">128</span>, <span class="number">1</span>))</span><br><span class="line">    model.summary()</span><br><span class="line">    </span><br><span class="line">    current_time = datetime.datetime.now().strftime(<span class="string">&quot;%Y%m%d-%H%M%S&quot;</span>)</span><br><span class="line">    log_dir = <span class="string">&#x27;logs/ResNet50_epoch50_Mstar_&#x27;</span> + current_time</span><br><span class="line">    tb_callback = callbacks.TensorBoard(log_dir=log_dir)</span><br><span class="line"></span><br><span class="line">    model.<span class="built_in">compile</span>(optimizer=optimizers.Adam(lr=<span class="number">0.0001</span>), loss=tf.losses.CategoricalCrossentropy(from_logits=<span class="literal">True</span>),</span><br><span class="line">            metrics=[<span class="string">&#x27;accuracy&#x27;</span>])</span><br><span class="line">    <span class="comment">#model.fit(train_db, epochs=1, validation_data=test_db,validation_freq=1)</span></span><br><span class="line"></span><br><span class="line">    model.fit(train_db, epochs=<span class="number">50</span>, validation_data=test_db,validation_freq=<span class="number">1</span>,callbacks=[tb_callback])</span><br><span class="line">    model.evaluate(test_db)</span><br><span class="line"></span><br><span class="line">    model.save_weights(<span class="string">&#x27;./checkpoint/ResNet50_epoch50_weights.ckpt&#x27;</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;save weights&#x27;</span>)</span><br><span class="line"></span><br><span class="line">    pred_labels = model.predict(test_images)</span><br><span class="line">    pred_labels = tf.argmax(pred_labels, axis=<span class="number">1</span>)</span><br><span class="line">    con_matrix = confusion_matrix(test_labels, pred_labels, labels=[<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>,<span class="number">8</span>,<span class="number">9</span>])</span><br><span class="line">    <span class="built_in">print</span>(con_matrix)</span><br><span class="line">    plot_confusion_matrix(con_matrix, test_label_names, normalize=<span class="literal">True</span>)</span><br><span class="line">    np.savetxt(<span class="string">&#x27;./checkpoint/ResNet50_epoch50_confusion_matrix.txt&#x27;</span>,con_matrix)</span><br><span class="line">    plt.show()</span><br></pre></td></tr></table></figure>

        </div>

        
            <section class="post-copyright">
                
                    <p class="copyright-item">
                        <span>Author:</span>
                        <span><a href="/about/">WD</a></span>
                    </p>
                
                
                    <p class="copyright-item">
                        <span>Permalink:</span>
                        <span><a href="https://did321.gitee.io/2021/07/05/%E5%9F%BA%E4%BA%8EResNet%E7%9A%84MSTAR%E6%95%B0%E6%8D%AE%E9%9B%86%E7%9B%AE%E6%A0%87%E5%88%86%E7%B1%BB/">https://did321.gitee.io/2021/07/05/%E5%9F%BA%E4%BA%8EResNet%E7%9A%84MSTAR%E6%95%B0%E6%8D%AE%E9%9B%86%E7%9B%AE%E6%A0%87%E5%88%86%E7%B1%BB/</a></span>
                    </p>
                
                
                    <p class="copyright-item">
                        <span>License:</span>
                        <span>Copyright (c) 2022 <a target="_blank" rel="noopener" href="http://creativecommons.org/licenses/by-nc/4.0/">CC-BY-NC-4.0</a> LICENSE</span>
                    </p>
                
                
                     <p class="copyright-item">
                         <span>Slogan:</span>
                         <span><a href="#">The blog is my giant.</a></span>
                     </p>
                

            </section>
        
        <section class="post-tags">
            <div>
                <span>Tag(s):</span>
                <span class="tag">
                    
                    
                        <a href="/tags/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/"># 深度学习</a>
                    
                        <a href="/tags/CNN/"># CNN</a>
                    
                        
                </span>
            </div>
            <div>
                <a href="javascript:window.history.back();">back</a>
                <span>· </span>
                <a href="/">home</a>
            </div>
        </section>
        <section class="post-nav">
            
                <a class="prev" rel="prev" href="/2021/07/28/ESP32-TFT-%E5%88%86%E5%85%89%E6%A3%B1%E9%95%9C%E5%AE%9E%E7%8E%B0%E9%80%8F%E6%98%8E%E5%B0%8F%E7%94%B5%E8%A7%86/">ESP32+TFT+分光棱镜实现透明小电视</a>
            
            
            <a class="next" rel="next" href="/2021/04/07/CNN-%E5%8F%91%E5%B1%95%E7%AE%80%E5%8F%B2/">CNN 发展简史</a>
            
        </section>
        <br>
        <br>
    
    <script src="//unpkg.com/valine/dist/Valine.min.js"></script>
    <div id="vcomments"></div>
    <script>
        new Valine({
    el: '#vcomments' ,

    appId: 'JvFy3ebVLo2rUYgHaMweJyXX-MdYXbMMI',
    appKey: 'TCFxfjDAM8UmERPEgYXJmT40',
    serverURLs: 'https://JvFy3ebV.api.lncldglobal.com', 
    placeholder: '----评论区----留下你的评论，作者会定期回复！在昵称处填写QQ号可自动获取邮箱和QQ头像（保护QQ邮箱隐私）',
    enableQQ: true,
    requiredFields: ['nick'],
});
    </script>

    </article>
</div>

        </div>
        <footer id="footer" class="footer">
    <div class="copyright">
        <span>© WD | Powered by <a href="https://hexo.io" target="_blank">Hexo</a> & <a href="https://github.com/Siricee/hexo-theme-Chic" target="_blank">Chic</a></span>
    </div>
</footer>

    </div>
</body>

</html>
